package com.itlong.cloud.service.impl;

import com.itlong.cloud.POJO.DTO.operate.DeadQueueGetPageDTO;
import com.itlong.cloud.POJO.PO.TimeTaskDeadMessageQueuePO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.dao.ITimeTaskDeadMessageQueueDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.ITimeTaskDeadMessageQueueService;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      死信队列表业务逻辑处理实现类。
 * </desc>
 *
 * @createDate 2017/11/16
 */
@Service
public class TimeTaskDeadMessageQueueServiceImpl implements ITimeTaskDeadMessageQueueService {
    @Autowired
    ITimeTaskDeadMessageQueueDao iTimeTaskDeadMessageQueueDao;

    @Autowired
    MessageSender messageSender;

    @Autowired
    RedisService redisService;


    /**
     * <desc>
     *      保存
     * <desc/>
     *
     * @param timeTaskDeadMessageQueuePO message消息
     * @return 影响结果
     * @author Wernchao.L
     * @createDate 2017/11/16
     */
    @Override
    public Integer save(TimeTaskDeadMessageQueuePO timeTaskDeadMessageQueuePO) throws Exception {
        Map<String,Object> msg= JsonUtil.toObject(timeTaskDeadMessageQueuePO.getMessageContent(), HashMap.class);
        //检测msg中的消息id是否已存在于死信队列消息表中，如果不存在则插入一条新消息
        if (iTimeTaskDeadMessageQueueDao.checkCorrelationId(msg.get("correlationId").toString()) == 0){
            return iTimeTaskDeadMessageQueueDao.save(SqlUtil.durableData(
                    timeTaskDeadMessageQueuePO, PlatformConstants.TABLE_SAVE));
        }else{
            //如果存在相同的消息，设置消费状态为未消费
            return iTimeTaskDeadMessageQueueDao.setMessageStatusError(msg.get("correlationId").toString());
        }
    }

    /**
     * <desc>
     *      获取分页数据
     * </desc>
     *
     * @param pageDTO 查询参数DTO
     * @return
     * @throws Exception
     * @author Jiaqi.X
     * @createDate 2017/11/29
     */
    @Override
    public Page<TimeTaskDeadMessageQueuePO> getPage(DeadQueueGetPageDTO pageDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<TimeTaskDeadMessageQueuePO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        page.setRows(iTimeTaskDeadMessageQueueDao.getPageList(params), iTimeTaskDeadMessageQueueDao.getPageCount(params));
        return page;
    }


    /**
     * <desc>
     *      发送死信
     * </desc>
     *
     * @param po
     * @author Jiaqi.X
     * @createDate 2017/11/29
     */
    @Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED)
    public void sendMessage(TimeTaskDeadMessageQueuePO po,boolean  needRetrive) throws Exception {
        if(needRetrive){
            po=iTimeTaskDeadMessageQueueDao.getOne(po);
        }
        messageSender.send(po.getQueueName(),po.getMessageContent(),po.getExchange(),po.getRoutingKey());
        //更新消息状态
        po.setMessageStatus(1);
        po.setConsumerNum(po.getConsumerNum()+1);
        po.setUpdateTime(new Date());
        iTimeTaskDeadMessageQueueDao.update(SqlUtil.durableData(po, PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *     定时任务检测错误的死信消息进行重发
     * </desc>
     *
     * @author Jiaqi.X
     * @createDate 2018/01/27
     */
    public void autoRedirectSendDeadMessage() throws Exception {
        List<TimeTaskDeadMessageQueuePO> list=iTimeTaskDeadMessageQueueDao.getRedirectDeadMessages();
        for(TimeTaskDeadMessageQueuePO deadQueue : list){
            this.sendMessage(deadQueue,false);
        }
    }


}
